/*
 * This activity is launched when the user has chosen to connect to a device.
 * It listens for events broadcast by the BluetoothLeService class, then 
 * shows a text message containing either the heart rate or error messages.
 */

package jens.nordmark.smartheartratemonitor;

import java.util.List;
import android.app.Activity;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

public class HeartRateActivity extends Activity {

    private BluetoothLeService myBluetoothLeService;
    private String myDeviceAddress;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_heart_rate);
		
		Log.d("HeartRateActivity.onCreate","1");
		Intent intent = getIntent();
		myDeviceAddress = intent.getStringExtra(MainActivity.HEARTRATE_DEVICE);
		Log.d("HeartRateActivity.onCreate deviceaddress",myDeviceAddress);
        registerReceiver(myGattUpdateReceiver, gattIntentFilter());

	}
	
	@Override
	protected void onStart() {
		super.onStart();
        Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
        boolean bindSuccess = bindService(gattServiceIntent, myServiceConnection, BIND_AUTO_CREATE);
        Log.d("HeartRateActivity.onStart bindService",Boolean.toString(bindSuccess));
	}
	
	@Override
	protected void onStop() {
		super.onStop();
        
	}

	/*
	 * Filters out the relevant broadcasts.
	 */
    private static IntentFilter gattIntentFilter() {
        final IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
        intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
        intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
        return intentFilter;
    }

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.heart_rate, menu);
		return true;
	}
	
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(myServiceConnection);
        myBluetoothLeService = null;
    }

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
	
	/*
	 * This code manages the connection to BluetoothLeService
	 */
	private final ServiceConnection myServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
    		Log.d("HeartRateActivity","Starting BT");
    		Intent intent = getIntent();
    		String myDeviceAddress = intent.getStringExtra(MainActivity.HEARTRATE_DEVICE);
            myBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
            if (!myBluetoothLeService.initialize()) {
                Log.d("ServiceConnection", "Unable to initialize Bluetooth");
                finish();
            }
    		Log.d("HeartRateActivity","Connecting to BT device");
    		Log.d("ServiceConnection", myDeviceAddress.toString());
            boolean connectSuccess = myBluetoothLeService.connect(myDeviceAddress);
            Log.d("ServiceConnection connected successfully?", Boolean.toString(connectSuccess));
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            myBluetoothLeService = null;
        }
    };
	
    /*
     * Receives all the broadcasts from the BluetoothLeService.
     */
	private final BroadcastReceiver myGattUpdateReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context arg0, Intent intent) {
			TextView heartrateDisplay = (TextView) findViewById(R.id.heart_rate_display);
			String action = intent.getAction();
			
			/*
			 * A new device has been connected
			 */
			if(BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)){
				heartrateDisplay.setText("connected");
				Log.d("Broadcastreceiver","ACTION_GATT_CONNECTED");
			}
			/*
			 * The device has been disconnected
			 */
			if(BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)){
				heartrateDisplay.setText("connected");
				Log.d("Broadcastreceiver","ACTION_GATT_DISCONNECTED");
			}
			/*
			 * Services have been found on the device, this code attempts to find a heartrate service on the
			 * device and activate notifications for the heart rate.
			 */
			if(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)){
				Log.d("Broadcastreceiver","ACTION_GATT_SERVICES_DISOVERED");
				for (BluetoothGattService gattService : myBluetoothLeService.getSupportedGattServices()) {
					Log.d("Broadcastreceiver",gattService.toString());
					if(gattService.getUuid().equals(BluetoothLeService.UUID_HEART_RATE_SERVICE)){
						List<BluetoothGattCharacteristic> characteristics = gattService.getCharacteristics();
						Log.d("Number of characteristics:",String.valueOf(characteristics.size()));
						for(BluetoothGattCharacteristic characteristic : characteristics){
							if(characteristic.getUuid().equals(BluetoothLeService.UUID_HEART_RATE_CHARACTERISTIC)){
								myBluetoothLeService.setCharacteristicNotification(characteristic, true);
								Log.d("Broadcastreceiver","Characteristicnotification activated");
							}
						}						
					}	
					else{
						heartrateDisplay.setText("Not connected \n or wrong device type.");
					}
				}
			}
			/*
			 * The device has data to send. If it is an error message, an error message is printed. Otherwise the
			 * data is assumed to be an integer representing the heartrate, and is displayed accordingly.
			 */
			if(BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)){
				String heartRate = intent.getStringExtra(BluetoothLeService.EXTRA_DATA);
				if(heartRate == BluetoothLeService.WRONG_DEVICE){
					heartrateDisplay.setText("Wrong device type");
				}
				else
				{
					heartrateDisplay.setText("Connected. \n Heart rate: \n" + heartRate);
				}
				Log.d("Broadcastreceiver","ACTION_DATA_AVAILABLE");
			}
		}
		
	};
}
